
<!DOCTYPE html>
<html>
  <head>
    <script src="https://unpkg.com/konva@4.0.18/konva.min.js"></script>
    <meta charset="utf-8" />
    <title>Konva Canvas Stage Preview Demo</title>
    <style>
      body {
        margin: 0;
        padding: 0;
        overflow: hidden;
        background-color: #f0f0f0;
      }

      #preview {
        position: absolute;
        top: 2px;
        right: 2px;
        border: 1px solid grey;
        background-color: lightgrey;
      }
    </style>
  </head>

  <body>
    <div id="container"></div>
    <div id="preview"></div>
    <script>
      const stage = new Konva.Stage({
        container: 'container',
        width: window.innerWidth,
        height: window.innerHeight
      });

      const layer = new Konva.Layer();
      stage.add(layer);

      // generate random shapes
      for (var i = 0; i < 10; i++) {
        const shape = new Konva.Circle({
          x: Math.random() * stage.width(),
          y: Math.random() * stage.height(),
          radius: Math.random() * 30 + 5,
          fill: Konva.Util.getRandomColor(),
          draggable: true,
          // each shape MUSH have uniq name
          // so we can easily update the preview clone by name
          name: 'shape-' + i
        });
        layer.add(shape);
      }

      layer.draw();

      // create smaller preview stage
      const previewStage = new Konva.Stage({
        container: 'preview',
        width: window.innerWidth / 4,
        height: window.innerHeight / 4,
        scaleX: 1 / 4,
        scaleY: 1 / 4
      });

      // clone original layer, and disable all events on it
      // we will use "let" here, because we can redefine layer later
      let previewLayer = layer.clone({ hitGraphEnabled: false });
      previewStage.add(previewLayer);

      function updatePreview() {
        // we just need to update ALL nodes in the preview
        layer.children.forEach(shape => {
          // find cloned node
          const clone = previewLayer.findOne('.' + shape.name());
          // update its position from the original
          clone.position(shape.position());
        });
        previewLayer.batchDraw();
      }

      stage.on('dragmove', updatePreview);

      // add new shapes on double click or double tap
      stage.on('dblclick dbltap', () => {
        const shape = new Konva.Circle({
          x: stage.getPointerPosition().x,
          y: stage.getPointerPosition().y,
          radius: Math.random() * 30 + 5,
          fill: Konva.Util.getRandomColor(),
          draggable: true,
          // each shape MUSH have uniq name
          // so we can easily update the preview clone by name
          name: 'shape-' + layer.children.length
        });
        layer.add(shape);
        layer.batchDraw();

        // remove all layer
        previewLayer.destroy();
        // generate new one
        previewLayer = layer.clone({ hitGraphEnabled: false });
        previewStage.add(previewLayer);
      });
    </script>
  </body>
</html>